//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension ObservabilityAdmin {
    // MARK: Enums

    public enum ResourceType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case awsEc2Instance = "AWS::EC2::Instance"
        case awsEc2Vpc = "AWS::EC2::VPC"
        case awsLamdbaFunction = "AWS::Lambda::Function"
        public var description: String { return self.rawValue }
    }

    public enum Status: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case failedStart = "FAILED_START"
        case failedStop = "FAILED_STOP"
        case notStarted = "NOT_STARTED"
        case running = "RUNNING"
        case starting = "STARTING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        public var description: String { return self.rawValue }
    }

    public enum TelemetryState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case disabled = "Disabled"
        case enabled = "Enabled"
        case notApplicable = "NotApplicable"
        public var description: String { return self.rawValue }
    }

    public enum TelemetryType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case logs = "Logs"
        case metrics = "Metrics"
        case traces = "Traces"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AccessDeniedException: AWSErrorShape {
        ///  The name of the exception.
        public let amznErrorType: String?
        public let message: String?

        @inlinable
        public init(amznErrorType: String? = nil, message: String? = nil) {
            self.amznErrorType = amznErrorType
            self.message = message
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.amznErrorType = try response.decodeHeaderIfPresent(String.self, key: "x-amzn-ErrorType")
            self.message = try container.decodeIfPresent(String.self, forKey: .message)
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
        }
    }

    public struct GetTelemetryEvaluationStatusForOrganizationOutput: AWSDecodableShape {
        ///  This field describes the reason for the failure status. The field will only be populated if Status is FAILED_START or FAILED_STOP.
        public let failureReason: String?
        ///  The onboarding status of the telemetry config feature for the organization.
        public let status: Status?

        @inlinable
        public init(failureReason: String? = nil, status: Status? = nil) {
            self.failureReason = failureReason
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case failureReason = "FailureReason"
            case status = "Status"
        }
    }

    public struct GetTelemetryEvaluationStatusOutput: AWSDecodableShape {
        ///  Describes the reason for the failure status. The field will only be populated if Status is FAILED_START or FAILED_STOP.
        public let failureReason: String?
        ///  The onboarding status of the telemetry config feature.
        public let status: Status?

        @inlinable
        public init(failureReason: String? = nil, status: Status? = nil) {
            self.failureReason = failureReason
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case failureReason = "FailureReason"
            case status = "Status"
        }
    }

    public struct InternalServerException: AWSErrorShape {
        ///  The name of the exception.
        public let amznErrorType: String?
        public let message: String?

        @inlinable
        public init(amznErrorType: String? = nil, message: String? = nil) {
            self.amznErrorType = amznErrorType
            self.message = message
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.amznErrorType = try response.decodeHeaderIfPresent(String.self, key: "x-amzn-ErrorType")
            self.message = try container.decodeIfPresent(String.self, forKey: .message)
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
        }
    }

    public struct ListResourceTelemetryForOrganizationInput: AWSEncodableShape {
        ///  A list of AWS account IDs used to filter the resources to those associated with the specified accounts.
        public let accountIdentifiers: [String]?
        ///  A number field used to limit the number of results within the returned list.
        public let maxResults: Int?
        ///  The token for the next set of items to return. A previous call provides this token.
        public let nextToken: String?
        ///  A string used to filter resources in the organization which have a ResourceIdentifier starting with the ResourceIdentifierPrefix.
        public let resourceIdentifierPrefix: String?
        ///  A key-value pair to filter resources in the organization based on tags associated with the resource. Fore more information about tags, see What are tags?
        public let resourceTags: [String: String]?
        ///  A list of resource types used to filter resources in the organization. If this parameter is provided, the resources will be returned in the same order used in the request.
        public let resourceTypes: [ResourceType]?
        ///  A key-value pair to filter resources in the organization based on the telemetry type and the state of the telemetry configuration. The key is the telemetry type and the value is the state.
        public let telemetryConfigurationState: [TelemetryType: TelemetryState]?

        @inlinable
        public init(accountIdentifiers: [String]? = nil, maxResults: Int? = nil, nextToken: String? = nil, resourceIdentifierPrefix: String? = nil, resourceTags: [String: String]? = nil, resourceTypes: [ResourceType]? = nil, telemetryConfigurationState: [TelemetryType: TelemetryState]? = nil) {
            self.accountIdentifiers = accountIdentifiers
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.resourceIdentifierPrefix = resourceIdentifierPrefix
            self.resourceTags = resourceTags
            self.resourceTypes = resourceTypes
            self.telemetryConfigurationState = telemetryConfigurationState
        }

        public func validate(name: String) throws {
            try self.accountIdentifiers?.forEach {
                try validate($0, name: "accountIdentifiers[]", parent: name, max: 12)
                try validate($0, name: "accountIdentifiers[]", parent: name, min: 12)
                try validate($0, name: "accountIdentifiers[]", parent: name, pattern: "^[0-9]{12}$")
            }
            try self.validate(self.accountIdentifiers, name: "accountIdentifiers", parent: name, max: 10)
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.resourceIdentifierPrefix, name: "resourceIdentifierPrefix", parent: name, max: 768)
            try self.validate(self.resourceIdentifierPrefix, name: "resourceIdentifierPrefix", parent: name, min: 3)
            try self.resourceTags?.forEach {
                try validate($0.key, name: "resourceTags.key", parent: name, max: 128)
                try validate($0.key, name: "resourceTags.key", parent: name, min: 1)
                try validate($0.key, name: "resourceTags.key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
                try validate($0.value, name: "resourceTags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "resourceTags[\"\($0.key)\"]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.resourceTags, name: "resourceTags", parent: name, max: 50)
            try self.validate(self.resourceTypes, name: "resourceTypes", parent: name, max: 5)
            try self.validate(self.resourceTypes, name: "resourceTypes", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case accountIdentifiers = "AccountIdentifiers"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case resourceIdentifierPrefix = "ResourceIdentifierPrefix"
            case resourceTags = "ResourceTags"
            case resourceTypes = "ResourceTypes"
            case telemetryConfigurationState = "TelemetryConfigurationState"
        }
    }

    public struct ListResourceTelemetryForOrganizationOutput: AWSDecodableShape {
        ///  The token for the next set of items to return. A previous call provides this token.
        public let nextToken: String?
        ///  A list of telemetry configurations for AWS resources supported by telemetry config in the organization.
        public let telemetryConfigurations: [TelemetryConfiguration]?

        @inlinable
        public init(nextToken: String? = nil, telemetryConfigurations: [TelemetryConfiguration]? = nil) {
            self.nextToken = nextToken
            self.telemetryConfigurations = telemetryConfigurations
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case telemetryConfigurations = "TelemetryConfigurations"
        }
    }

    public struct ListResourceTelemetryInput: AWSEncodableShape {
        ///  A number field used to limit the number of results within the returned list.
        public let maxResults: Int?
        ///  The token for the next set of items to return. A previous call generates this token.
        public let nextToken: String?
        ///  A string used to filter resources which have a ResourceIdentifier starting with the ResourceIdentifierPrefix.
        public let resourceIdentifierPrefix: String?
        ///  A key-value pair to filter resources based on tags associated with the resource. For more information about tags, see What are tags?
        public let resourceTags: [String: String]?
        ///  A list of resource types used to filter resources supported by telemetry config. If this parameter is provided, the resources will be returned in the same order used in the request.
        public let resourceTypes: [ResourceType]?
        ///  A key-value pair to filter resources based on the telemetry type and the state of the telemetry configuration. The key is the telemetry type and the value is the state.
        public let telemetryConfigurationState: [TelemetryType: TelemetryState]?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, resourceIdentifierPrefix: String? = nil, resourceTags: [String: String]? = nil, resourceTypes: [ResourceType]? = nil, telemetryConfigurationState: [TelemetryType: TelemetryState]? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.resourceIdentifierPrefix = resourceIdentifierPrefix
            self.resourceTags = resourceTags
            self.resourceTypes = resourceTypes
            self.telemetryConfigurationState = telemetryConfigurationState
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.resourceIdentifierPrefix, name: "resourceIdentifierPrefix", parent: name, max: 768)
            try self.validate(self.resourceIdentifierPrefix, name: "resourceIdentifierPrefix", parent: name, min: 3)
            try self.resourceTags?.forEach {
                try validate($0.key, name: "resourceTags.key", parent: name, max: 128)
                try validate($0.key, name: "resourceTags.key", parent: name, min: 1)
                try validate($0.key, name: "resourceTags.key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
                try validate($0.value, name: "resourceTags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "resourceTags[\"\($0.key)\"]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.resourceTags, name: "resourceTags", parent: name, max: 50)
            try self.validate(self.resourceTypes, name: "resourceTypes", parent: name, max: 5)
            try self.validate(self.resourceTypes, name: "resourceTypes", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case resourceIdentifierPrefix = "ResourceIdentifierPrefix"
            case resourceTags = "ResourceTags"
            case resourceTypes = "ResourceTypes"
            case telemetryConfigurationState = "TelemetryConfigurationState"
        }
    }

    public struct ListResourceTelemetryOutput: AWSDecodableShape {
        ///  The token for the next set of items to return. A previous call generates this token.
        public let nextToken: String?
        ///  A list of telemetry configurations for AWS resources supported by telemetry config in the caller's account.
        public let telemetryConfigurations: [TelemetryConfiguration]?

        @inlinable
        public init(nextToken: String? = nil, telemetryConfigurations: [TelemetryConfiguration]? = nil) {
            self.nextToken = nextToken
            self.telemetryConfigurations = telemetryConfigurations
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case telemetryConfigurations = "TelemetryConfigurations"
        }
    }

    public struct TelemetryConfiguration: AWSDecodableShape {
        ///  The account ID which contains the resource managed in telemetry configuration. An example of a valid account ID is 012345678901.
        public let accountIdentifier: String?
        ///  The timestamp of the last change to the telemetry configuration for the resource.  For example, 1728679196318.
        public let lastUpdateTimeStamp: Int64?
        ///  The identifier of the resource, for example i-0b22a22eec53b9321.
        public let resourceIdentifier: String?
        ///  Tags associated with the resource, for example { Name: "ExampleInstance", Environment: "Development" }.
        public let resourceTags: [String: String]?
        ///  The type of resource, for example AWS::EC2::Instance.
        public let resourceType: ResourceType?
        ///  The configuration state for the resource, for example { Logs: NotApplicable; Metrics: Enabled; Traces: NotApplicable; }.
        public let telemetryConfigurationState: [TelemetryType: TelemetryState]?

        @inlinable
        public init(accountIdentifier: String? = nil, lastUpdateTimeStamp: Int64? = nil, resourceIdentifier: String? = nil, resourceTags: [String: String]? = nil, resourceType: ResourceType? = nil, telemetryConfigurationState: [TelemetryType: TelemetryState]? = nil) {
            self.accountIdentifier = accountIdentifier
            self.lastUpdateTimeStamp = lastUpdateTimeStamp
            self.resourceIdentifier = resourceIdentifier
            self.resourceTags = resourceTags
            self.resourceType = resourceType
            self.telemetryConfigurationState = telemetryConfigurationState
        }

        private enum CodingKeys: String, CodingKey {
            case accountIdentifier = "AccountIdentifier"
            case lastUpdateTimeStamp = "LastUpdateTimeStamp"
            case resourceIdentifier = "ResourceIdentifier"
            case resourceTags = "ResourceTags"
            case resourceType = "ResourceType"
            case telemetryConfigurationState = "TelemetryConfigurationState"
        }
    }
}

// MARK: - Errors

/// Error enum for ObservabilityAdmin
public struct ObservabilityAdminErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case internalServerException = "InternalServerException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize ObservabilityAdmin
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    ///  Indicates you don't have permissions to perform the requested operation. The user or role that is making the request must have at least one IAM permissions policy attached that grants the required permissions. For more information, see Access management for AWS resources in the IAM user guide.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    ///  Indicates the request has failed to process because of an unknown server error, exception, or failure.
    public static var internalServerException: Self { .init(.internalServerException) }
    ///  Indicates input validation failed. Check your request parameters and retry the request.
    public static var validationException: Self { .init(.validationException) }
}

extension ObservabilityAdminErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "AccessDeniedException": ObservabilityAdmin.AccessDeniedException.self,
        "InternalServerException": ObservabilityAdmin.InternalServerException.self
    ]
}

extension ObservabilityAdminErrorType: Equatable {
    public static func == (lhs: ObservabilityAdminErrorType, rhs: ObservabilityAdminErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension ObservabilityAdminErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
